package org.tlipoca.smusersubscribe.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.genntii.smcommon.constant.ExceptionConstant;
import org.genntii.smcommon.exception.ChannelNotFoundException;
import org.genntii.smcommon.exception.ParamErrorException;
import org.genntii.smcommon.exception.SubscribeIDDuplicatesException;
import org.genntii.smcommon.exception.UserNotFoundException;
import org.genntii.smcommon.utils.DateUtil;
import org.genntii.smdomain.dto.UserSubscribeDTO;
import org.genntii.smdomain.entity.Channel;
import org.genntii.smdomain.entity.UserSubscribe;
import org.genntii.smdomain.vo.SubscribeNumVO;
import org.genntii.smdomain.vo.UserSubScribeClientVO;
import org.genntii.smdomain.vo.UserSubscribeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.tlipoca.smusersubscribe.client.ArticleClient;
import org.tlipoca.smusersubscribe.client.ChannelClient;
import org.tlipoca.smusersubscribe.client.UserClient;
import org.tlipoca.smusersubscribe.mapper.UserSubscribeMapper;
import org.tlipoca.smusersubscribe.service.UserSubscribeService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class UserSubscribeServiceImpl extends ServiceImpl<UserSubscribeMapper, UserSubscribe> implements UserSubscribeService {

    @Autowired
    private UserSubscribeMapper userSubscribeMapper;

    @Autowired
    private UserClient userClient;

    @Autowired
    private ChannelClient channelClient;

    @Resource
    private ArticleClient articleClient;

    @Override
    public Byte userSubscribed(Byte type, Long targetId, Long userId) {
        switch (type){
            case 1:
                // 频道
                UserSubscribe channelSubscribe = userSubscribeMapper.channelSubscribed(userId,targetId);
                if (channelSubscribe == null){
                    return 0;
                }
                break;
            case 2:
                // 用户
                UserSubscribe userSubscribe = userSubscribeMapper.userSubscribed(userId, targetId);
                if (userSubscribe == null){
                    return 0;
                }
                break;
            default:
                throw new ParamErrorException(ExceptionConstant.PARAM_ERROR_EXCEPTION);
        }
        return 1;
    }

    @Override
    public SubscribeNumVO getSubscribeNum(Long userId) {
        return new SubscribeNumVO(userSubscribeMapper.getSubscribeNum(userId),userSubscribeMapper.getSubscribedNum(userId));
    }

    /**
     * 查找关注频道
     * @param userId
     * @return
     */
    @Override
    public ArrayList<UserSubscribeVO> getUserSubscribeChannelListService(Long userId) {
        ArrayList<UserSubscribe> channelList = (ArrayList<UserSubscribe>) userSubscribeMapper.selectList(new QueryWrapper<UserSubscribe>().eq("user_id",userId).eq("subscriber_user_id",0));
        ArrayList<UserSubscribeVO> voList = new ArrayList<>();

        ArrayList<Long> channelIds = new ArrayList<>();
        for (UserSubscribe userSubscribe:channelList){
            channelIds.add(userSubscribe.getChannelId());
        }
        ArrayList<Channel> data = channelClient.getChannelBatch(channelIds).getData();
        if (data == null || data.isEmpty()){
            return null;
        }
        Map<Long, Channel> channelMap = new HashMap<>();
        for (Channel channel:data){
            channelMap.put(channel.getId(),channel);
        }

        for (UserSubscribe userSubscribe: channelList){
            UserSubscribeVO vo = UserSubscribeVO.builder()
                    .id(userSubscribe.getUserId())
                    .userId(userSubscribe.getUserId())
                    .channelId(userSubscribe.getChannelId())
                    .channelName(channelMap.get(userSubscribe.getChannelId()).getChannelName())
                    .channelIcon(channelMap.get(userSubscribe.getChannelId()).getChannelIcon())
                    .build();
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public ArrayList<UserSubscribeVO> getUserSubscribeUserListService(Long userId) {
        ArrayList<UserSubscribe> subscriberList = (ArrayList<UserSubscribe>) userSubscribeMapper.selectList(new QueryWrapper<UserSubscribe>().eq("user_id",userId).eq("channel_id",0));
        ArrayList<UserSubscribeVO> voList = new ArrayList<>();
        for (UserSubscribe userSubscribe:subscriberList){
            UserSubscribeVO vo = UserSubscribeVO.builder()
                    .id(userSubscribe.getUserId())
                    .userId(userSubscribe.getUserId())
                    .subscriberUserId(userSubscribe.getSubscriberUserId())
                    .subscriberName(userClient.getUserById(userSubscribe.getUserId()).getData().getNickname())
                    .subscriberAvatar(userClient.getUserById(userSubscribe.getUserId()).getData().getAvatar())
                    .build();
            voList.add(vo);
        }
        return voList;
    }

    @Override
    public void userSubscribeServiceService(Long userId, UserSubscribeDTO userSubscribeDTO) {

        if (userSubscribeDTO.getUserId()!=0&&userSubscribeDTO.getChannelId()!= 0){
            throw new SubscribeIDDuplicatesException(ExceptionConstant.METHOD_DONT_ALLOWED);
        }

        if (userSubscribeDTO.getUserId() != 0) {
            // 关注用户
            log.info("用户 {} 关注用户 {}", userId, userSubscribeDTO.getUserId());

            // 判断用户是否存在
            if(userClient.userIdExists(userSubscribeDTO.getUserId()).getData()==Boolean.FALSE) {
                System.out.println(userClient.userIdExists(userSubscribeDTO.getUserId()).getData()==Boolean.FALSE);
                throw new UserNotFoundException(ExceptionConstant.USER_NOT_FOUND_EXCEPTION);
            }

            // 判断是否已关注
            if (userSubscribeMapper.exists(
                    new QueryWrapper<UserSubscribe>()
                            .eq("subscriber_user_id", userSubscribeDTO.getUserId())
                            .eq("user_id", userId))
            ) {
                throw new SubscribeIDDuplicatesException(ExceptionConstant.SUBSCRIBE_ID_DUPLICATES_EXCEPTION);
            }

            UserSubscribe userSubscribe = UserSubscribe.builder()
                    .userId(userId)
                    .subscriberUserId(userSubscribeDTO.getUserId())
                    .build();

            // 新增用户关注
            userSubscribeMapper.insert(userSubscribe);

            articleClient.setFollower(userSubscribeMapper.getSubscribedNum(userSubscribeDTO.getUserId()),userSubscribeDTO.getUserId());
        }

        if (userSubscribeDTO.getChannelId() != 0) {
            // 关注频道
            log.info("用户 {} 关注频道 {}", userId, userSubscribeDTO.getChannelId());

            // 判断频道是否存在
            if(channelClient.channelExists(userSubscribeDTO.getChannelId()).getData()==Boolean.FALSE) {
                throw new ChannelNotFoundException(ExceptionConstant.CHANNEL_NOT_FOUND_EXCEPTION);
            }

            // 判断是否已关注
            if (userSubscribeMapper.exists(new QueryWrapper<UserSubscribe>().eq("subscriber_user_id", userId).eq("channel_id", userSubscribeDTO.getChannelId()))) {
                throw new SubscribeIDDuplicatesException(ExceptionConstant.SUBSCRIBE_ID_DUPLICATES_EXCEPTION);
            }

            UserSubscribe userSubscribe = UserSubscribe.builder()
                    .channelId(userSubscribeDTO.getChannelId())
                    .userId(userId)
                    .build();

            // 新增用户关注
            userSubscribeMapper.insert(userSubscribe);
        }

    }

    @Override
    public void userCancelSubscribeService(Long userId, UserSubscribeDTO userSubscribeDTO) {

        if (userSubscribeDTO.getUserId()!=0&&userSubscribeDTO.getChannelId()!= 0){
            throw new SubscribeIDDuplicatesException(ExceptionConstant.METHOD_DONT_ALLOWED);
        }

        if (userSubscribeDTO.getUserId() != 0) {
            // 取消关注用户
            log.info("用户 {} 取消关注用户 {}", userId, userSubscribeDTO.getUserId());

            // 判断用户是否存在
            if(userClient.userIdExists(userSubscribeDTO.getUserId()).getData()==Boolean.FALSE) {
                throw new UserNotFoundException(ExceptionConstant.USER_NOT_FOUND_EXCEPTION);
            }

            // 判断是否已关注
            if (!userSubscribeMapper.exists(new QueryWrapper<UserSubscribe>().eq("subscriber_user_id",userSubscribeDTO.getUserId() ).eq("user_id", userId))) {
                throw new SubscribeIDDuplicatesException(ExceptionConstant.SUBSCRIBE_ID_DUPLICATES_EXCEPTION);
            }

            // 取消关注
            userSubscribeMapper.deleteSubscribeUser(userSubscribeDTO.getUserId(),userId);

            articleClient.setFollower(userSubscribeMapper.getSubscribedNum(userSubscribeDTO.getUserId()),userSubscribeDTO.getUserId());
        }

        if (userSubscribeDTO.getChannelId() != 0) {
            // 取消关注频道
            log.info("用户 {} 取消关注频道 {}", userId, userSubscribeDTO.getChannelId());

            // 判断频道是否存在
            if(channelClient.channelExists(userSubscribeDTO.getChannelId()).getData()==Boolean.FALSE) {
                throw new ChannelNotFoundException(ExceptionConstant.CHANNEL_NOT_FOUND_EXCEPTION);
            }

            // 判断是否已关注
            if (!userSubscribeMapper.exists(new QueryWrapper<UserSubscribe>().eq("subscriber_user_id", userSubscribeDTO.getUserId()).eq("channel_id", userSubscribeDTO.getChannelId()))) {
                throw new SubscribeIDDuplicatesException(ExceptionConstant.SUBSCRIBE_ID_DUPLICATES_EXCEPTION);
            }

            // 取消关注
            userSubscribeMapper.deleteSubscribeChannel(userId, userSubscribeDTO.getChannelId());
        }

    }

    @Override
    public ArrayList<UserSubScribeClientVO> subscribe8c(Long userId) {
        ArrayList<UserSubscribe> userSubscribes = userSubscribeMapper.subscribe8c(userId);
        ArrayList<UserSubScribeClientVO> userSubScribeClientVOS = new ArrayList<>();
        for (UserSubscribe userSubscribe:userSubscribes){
            userSubScribeClientVOS.add(UserSubScribeClientVO.builder()
                    .id(userSubscribe.getId())
                    .channelId(userSubscribe.getChannelId())
                    .subscriberUserId(userSubscribe.getSubscriberUserId())
                    .userId(userSubscribe.getUserId())
                    .createTime(DateUtil.toString(userSubscribe.getCreateTime()))
                    .build());
        }
        return userSubScribeClientVOS;
    }

    @Override
    public ArrayList<UserSubScribeClientVO> subscribe8u(Long userId) {
        ArrayList<UserSubscribe> userSubscribes = userSubscribeMapper.subscribe8u(userId);
        ArrayList<UserSubScribeClientVO> userSubScribeClientVOS = new ArrayList<>();
        for (UserSubscribe userSubscribe:userSubscribes){
            userSubScribeClientVOS.add(UserSubScribeClientVO.builder()
                    .id(userSubscribe.getId())
                    .channelId(userSubscribe.getChannelId())
                    .subscriberUserId(userSubscribe.getSubscriberUserId())
                    .userId(userSubscribe.getUserId())
                    .createTime(DateUtil.toString(userSubscribe.getCreateTime()))
                    .build());
        }
        return userSubScribeClientVOS;
    }
}
